package com.link.base.tencent.corpwx.addressbook.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.link.base.tencent.corpwx.addressbook.model.User;
import com.link.base.wechat.basic.util.WxExceptionUtil;
import com.link.core.basic.service.BasicServiceException;
import com.link.core.util.HttpRequestUtil;
import com.link.core.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 企业微信通讯录成员管理
 *
 * @author 李宗庭
 * @date 2019/1/29
 */
public class UserUtil {
    /**请求成功码*/
    private static final String WX_REQ_SUCCESS_CODE = "0";
    /**userId不存在返回的code*/
    private static final String WX_NO_USER_CODE = "60111";
    /**创建成员接口*/
    private static final String CREATE_USER_API = "https://qyapi.weixin.qq.com/cgi-bin/user/create?access_token=ACCESS_TOKEN";
    /**更新成员接口*/
    private static final String UPDATE_USER_API = "https://qyapi.weixin.qq.com/cgi-bin/user/update?access_token=ACCESS_TOKEN";
    /**删除成员接口*/
    private static final String DELETE_USER_API = "https://qyapi.weixin.qq.com/cgi-bin/user/delete?access_token=ACCESS_TOKEN&userid=USERID";
    /**批量删除成员接口*/
    private static final String BATCH_DELETE_USER_API = "https://qyapi.weixin.qq.com/cgi-bin/user/batchdelete?access_token=ACCESS_TOKEN";
    /**读取成员接口*/
    private static final String GET_USER_API = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&userid=USERID";
    /**获取部门成员接口 - 简单版*/
    private static final String GET_DEPT_SIMPLE_USER_API =
        "https://qyapi.weixin.qq.com/cgi-bin/user/simplelist?access_token=ACCESS_TOKEN&department_id=DEPARTMENT_ID&fetch_child=FETCH_CHILD";
    /**获取部门成员接口 - 详情版版*/
    private static final String GET_DEPT_DATAIL_USER_API =
        "https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=ACCESS_TOKEN&department_id=DEPARTMENT_ID&fetch_child=FETCH_CHILD";
    /**userId转openId接口*/
    private static final String USERID_CONVERT_TO_OPENID_API = "https://qyapi.weixin.qq.com/cgi-bin/user/convert_to_openid?access_token=ACCESS_TOKEN";
    /**全量覆盖成员接口*/
    private static final String BATCH_REPLACE_USER_API = "https://qyapi.weixin.qq.com/cgi-bin/batch/replaceuser?access_token=ACCESS_TOKEN";
    /**增量更新成员接口*/
    private static final String BATCH_UPDATE_USER_API = "https://qyapi.weixin.qq.com/cgi-bin/batch/syncuser?access_token=ACCESS_TOKEN";
    /**获取异步任务结果接口*/
    private static final String GET_BATCH_JOB_RESULT_API = "https://qyapi.weixin.qq.com/cgi-bin/batch/getresult?access_token=ACCESS_TOKEN&jobid=JOBID";

    /**
     * 新增企业微信通讯录用户
     *
     * @author 李宗庭
     * @date 2019/2/22
     * @param accessToken
     */
    public static JSONObject newWxUser(String accessToken, User user) throws Exception {
        if (StringUtils.isBlank(accessToken)) {
            throw new BasicServiceException("accessToken不能为空！");
        }
        if (StringUtils.isBlank(user.getUserId())) {
            throw new BasicServiceException("userId不能为空！");
        }
        if (StringUtils.isBlank(user.getMobile())) {
            throw new BasicServiceException("用户手机号不能为空！");
        }
        if (StringUtils.isBlank(user.getDepartment())) {
            throw new BasicServiceException("用户所属部门不能为空！");
        }
        String url = CREATE_USER_API.replace("ACCESS_TOKEN", accessToken);
        JSONObject paramObj = new JSONObject();
        paramObj.put("userid", user.getUserId());
        paramObj.put("name", user.getName());
        paramObj.put("mobile", user.getMobile());
        String maleString = "MALE";
        String femaleString = "FEMALE";
        if (maleString.equals(user.getGender())) {
            paramObj.put("gender", "1");
        } else if (femaleString.equals(user.getGender())) {
            paramObj.put("gender", "2");
        }
        if (StringUtils.isNotBlank(user.getPosition())) {
            paramObj.put("position", user.getPosition());
        }
        if (StringUtils.isNotBlank(user.getEmail())) {
            paramObj.put("email", user.getEmail());
        }
        Boolean toInvite = false;
        String yString = "Y";
        if (StringUtils.isNotBlank(user.getToInvite())) {
            toInvite = yString.equals(user.getToInvite());
        }
        paramObj.put("to_invite", toInvite);
        List<String> deptList = getListFromString(user.getDepartment());
        paramObj.put("department", deptList);
        String param = paramObj.toJSONString();
        String resultStr = HttpRequestUtil.jsonPost(url, param);
        return WxExceptionUtil.parse(resultStr);
    }

    /**
     * 更新企业微信通讯录用户
     *
     * @author 李宗庭
     * @date 2019/2/22
     * @param accessToken
     * @param user
     */
    public static JSONObject updateWxUser(String accessToken, User user) throws Exception {
        if (StringUtils.isBlank(accessToken)) {
            throw new BasicServiceException("accessToken不能为空！");
        }
        if (StringUtils.isBlank(user.getUserId())) {
            throw new BasicServiceException("userId不能为空！");
        }
        String url = UPDATE_USER_API.replace("ACCESS_TOKEN", accessToken);
        JSONObject paramObj = new JSONObject();
        paramObj.put("userid", user.getUserId());
        if (StringUtils.isNotBlank(user.getName())) {
            paramObj.put("name", user.getName());
        }
        String maleString = "MALE";
        String femaleString = "FEMALE";
        if (maleString.equals(user.getGender())) {
            paramObj.put("gender", "1");
        } else if (femaleString.equals(user.getGender())) {
            paramObj.put("gender", "2");
        }
        if (StringUtils.isNotBlank(user.getPosition())) {
            paramObj.put("position", user.getPosition());
        }
        if (StringUtils.isNotBlank(user.getEmail())) {
            paramObj.put("email", user.getEmail());
        }
        if (StringUtils.isNotBlank(user.getMobile())) {
            paramObj.put("mobile", user.getMobile());
        }
        List<String> deptList = getListFromString(user.getDepartment());
        if (StringUtils.isNotBlank(user.getDepartment())) {
            paramObj.put("department", deptList);
        }
        String param = paramObj.toJSONString();
        String resultStr = HttpRequestUtil.jsonPost(url, param);
        return WxExceptionUtil.parse(resultStr);
    }

    /**
     * 删除企业微信的通讯录成员
     *
     * @author 李宗庭
     * @date 2019/2/22
     * @param accessToken
     * @param userId
     */
    public static JSONObject deleteWxUser(String accessToken, String userId) throws Exception {
        if (StringUtils.isBlank(accessToken)) {
            throw new BasicServiceException("accessToken不能为空！");
        }
        if (StringUtils.isBlank(userId)) {
            throw new BasicServiceException("userId不能为空！");
        }
        String url = DELETE_USER_API.replace("ACCESS_TOKEN", accessToken).replace("USERID", userId);
        String resultStr = HttpRequestUtil.sendGet(url, "");
        return WxExceptionUtil.parse(resultStr);
    }

    /**
     * 批量删除企业微信的通讯录成员
     *
     * @author 李宗庭
     * @date 2019/2/22
     * @param accessToken
     * @param userIds
     */
    public static JSONObject deleteWxUsers(String accessToken, List<String> userIds) throws Exception {
        if (StringUtils.isBlank(accessToken)) {
            throw new BasicServiceException("accessToken不能为空！");
        }
        if (userIds == null || userIds.size() <= 0) {
            throw new BasicServiceException("待删除的用户列表不能为空！");
        }
        int maxLength = 200;
        if (userIds.size() > maxLength) {
            throw new BasicServiceException("选择待删除的人数不能多于{0}！", String.valueOf(maxLength));
        }
        String url = BATCH_DELETE_USER_API.replace("ACCESS_TOKEN", accessToken);
        JSONObject userIdsObject = new JSONObject();
        userIdsObject.put("useridlist", userIds);
        String resultStr = HttpRequestUtil.jsonPost(url, userIdsObject.toJSONString());
        return WxExceptionUtil.parse(resultStr);
    }


    /**
     * 通过用户Id查询企业微信通讯录成员
     *
     * @author 李宗庭
     * @date 2019/2/22
     * @param accessToken
     * @param userId
     * @return User
     */
    public static User queryWxUserById(String accessToken, String userId) throws Exception {
        if (StringUtils.isBlank(accessToken)) {
            throw new BasicServiceException("accessToken不能为空！");
        }
        if (StringUtils.isBlank(userId)) {
            throw new BasicServiceException("userId不能为空！");
        }
        String url = GET_USER_API.replace("ACCESS_TOKEN", accessToken).replace("USERID", userId);
        String resultStr = HttpRequestUtil.sendGet(url, "");
        JSONObject userObject = JSONObject.parseObject(resultStr);
        String errCode = userObject.getString("errcode");
        User result;
        if (errCode.equals(WX_REQ_SUCCESS_CODE)) {
            result =  getUserFromJson(userObject);
        } else if (errCode.equals(WX_NO_USER_CODE)) {
            result = null;
        } else {
            throw new Exception(userObject.getString("errmsg"));
        }
        return result;
    }

    /**
     * 获取部门成员
     *
     * @date 2019/2/22
     * @author 李宗庭
     * @param accessToken
     * @param deptId         企业微信中的部门Id
     * @param fetchChildFlag 是否递归获取子部门下面的成员,true表示递归查询
     * @param detailFlag     是否查询员工详情
     * @return User
     */
    public static List<User> queryWxUsersByDepartment(String accessToken, String deptId, Boolean fetchChildFlag, Boolean detailFlag)
            throws Exception {
        if (StringUtils.isBlank(accessToken)) {
            throw new BasicServiceException("accessToken不能为空！");
        }
        if (StringUtils.isBlank(deptId)) {
            throw new BasicServiceException("deptId不能为空！");
        }
        String fetchChild = "0";
        if (fetchChildFlag) {
            fetchChild = "1";
        }
        String url = GET_DEPT_SIMPLE_USER_API;
        if (detailFlag) {
            url = GET_DEPT_DATAIL_USER_API;
        }
        url = url.replace("ACCESS_TOKEN", accessToken).replace("DEPARTMENT_ID", deptId).replace("FETCH_CHILD", fetchChild);
        String resultStr = HttpRequestUtil.sendGet(url, "");
        JSONObject usersObject = WxExceptionUtil.parse(resultStr);
        JSONArray userList = usersObject.getJSONArray("userlist");
        List<User> result = new ArrayList<>();
        for (int i = 0; i < userList.size(); i++) {
            User user = new User();
            JSONObject obj = userList.getJSONObject(i);
            if (detailFlag) {
                user = getUserFromJson(obj);
            } else {
                user.setUserId(obj.getString("userid"));
                user.setName(obj.getString("name"));
                String deptList = getListFromJson("department", obj);
                user.setDepartment(deptList);
            }
            result.add(user);
        }
        return result;
    }

    /**
     * 从一个JsonObject取出相应key的json数组并返回List数据格式
     *
     * @author 李宗庭
     * @date 2019/2/22
     * @param key
     * @return List
     */
    static String getListFromJson(String key, JSONObject object) {
        String result = "";
        JSONArray jsonArray = object.getJSONArray(key);
        StringBuilder tempString = new StringBuilder();
        for (Object item : jsonArray) {
            tempString.append(item.toString()).append(";");
        }
        result = tempString + "";
        return result;
    }

    /**
     * 从一个JsonObject解析出User对象
     *
     * @author 李宗庭
     * @date 2019/2/22
     * @param object
     * @return User
     */
    static User getUserFromJson(JSONObject object) {
        User user = new User();
        user.setUserId(object.getString("userid"));
        user.setName(object.getString("name"));
        user.setPosition(object.getString("position"));
        user.setMobile(object.getString("mobile"));
        user.setEmail(object.getString("email"));
        String deptList = getListFromJson("department", object);
        user.setDepartment(deptList);
        user.setAlias(object.getString("alias"));
        String orderList = getListFromJson("order", object);
        user.setOrder(orderList);
        String isLeadList = getListFromJson("is_leader_in_dept", object);
        user.setIsLeaderInDept(isLeadList);
        user.setGender(object.getString("gender"));
        user.setAvatar(object.getString("avatar"));
        user.setTelephone(object.getString("telephone"));
        user.setEnable(object.getString("enable"));
        user.setStatus(object.getString("status"));
        user.setQrCode(object.getString("qr_code"));
        return user;
    }

    /**
    * 通过字符串得到List，用于有；分割的字段
     *
    * @author 李宗庭
    * @param  record
    * @date 2019/2/28
    */
    static List<String> getListFromString(String record) {
        List<String> list = new ArrayList<>();
        if (StringUtils.isNotBlank(record)) {
            String[] array = record.split(";");
            for (String item: array) {
                list.add(item);
            }
        }
        return list;
    }

    /**
     * userID 转 openId
     *
     * @author liying
     * @date 2019/02/21
     * @param  accessToken token
     * @param userId 用户id
     */
    public static JSONObject transformOpenId(String accessToken, String userId) throws Exception {
        if (StringUtils.isBlank(accessToken)) {
            throw new BasicServiceException("accessToken不能为空！");
        }
        String url = USERID_CONVERT_TO_OPENID_API.replace("ACCESS_TOKEN", accessToken);
        JSONObject obj = new JSONObject();
        obj.put("userid", userId);
        String content = obj.toJSONString();
        String result = HttpRequestUtil.jsonPost(url, content);

        return WxExceptionUtil.parse(result);
    }

    /**
    * 全量覆盖通讯录成员
     *
    * @author 李宗庭
    * @param accessToken
    * @param mediaId
    * @param inviteFlag 同步完用户是否邀请其加入企业微信，将通过微信服务通知或短信或邮件下发邀请，每天自动下发一次，最多持续3个工作日
    * @date 2019/3/7
    */
    public static JSONObject batchReplaceUser(String accessToken, String mediaId, Boolean inviteFlag) throws Exception {
        if (StringUtils.isBlank(accessToken)) {
            throw new BasicServiceException("accessToken不能为空！");
        }
        String url = BATCH_REPLACE_USER_API.replace("ACCESS_TOKEN", accessToken);
        JSONObject obj = new JSONObject();
        obj.put("media_id", mediaId);
        obj.put("to_invite", inviteFlag);
        String param = obj.toJSONString();
        String resultStr = HttpRequestUtil.jsonPost(url, param);
        return WxExceptionUtil.parse(resultStr);
    }

    /**
     * 增量更新通讯录成员
     *
     * @author 李宗庭
     * @param accessToken
     * @param mediaId
     * @param inviteFlag 同步完用户是否邀请其加入企业微信，将通过微信服务通知或短信或邮件下发邀请，每天自动下发一次，最多持续3个工作日
     * @date 2019/3/7
     */
    public static JSONObject batchSyncUser(String accessToken, String mediaId, Boolean inviteFlag) throws Exception {
        if (StringUtils.isBlank(accessToken)) {
            throw new BasicServiceException("accessToken不能为空！");
        }
        String url = BATCH_UPDATE_USER_API.replace("ACCESS_TOKEN", accessToken);
        JSONObject obj = new JSONObject();
        obj.put("media_id", mediaId);
        obj.put("to_invite", inviteFlag);
        String param = obj.toJSONString();
        String resultStr = HttpRequestUtil.jsonPost(url, param);
        return WxExceptionUtil.parse(resultStr);
    }

    /**
    * 获取异步任务的结果
     *
    * @author 李宗庭
    * @param
    * @return
    * @date 2019/3/18
    */
    public static JSONObject getTaskResult(String accessToken, String jobId) throws Exception {
        if (StringUtils.isBlank(accessToken)) {
            throw new BasicServiceException("accessToken不能为空！");
        }
        if (StringUtils.isBlank(jobId)) {
            throw new BasicServiceException("jobId不能为空！");
        }
        String url = GET_BATCH_JOB_RESULT_API.replace("ACCESS_TOKEN", accessToken).replace("JOBID", jobId);
        String resultStr = HttpRequestUtil.sendGet(url, "");
        return WxExceptionUtil.parse(resultStr);
    }
}
